#include "LandPatternWidget.h"

#include "LeGraphicsView/LeGraphicsFeatureOption.h"
#include "LeGraphicsView/LeGraphicsItem.h"
#include "LeGraphicsView/LeGraphicsItemLayer.h"
#include "LeGraphicsView/LeGraphicsPalette.h"
#include "LeGraphicsView/LeGraphicsScene.h"
#include "LeGraphicsView/LeGraphicsStyle.h"
#include "LeGraphicsView/LeGraphicsView.h"
#include "LeGraphicsView/Solarized.h"

#include "GraphicsItems.h"
#include "AbstractTask.h"

#include "LeDocumentObject/Document.h"

#include "LeIpc7351/PadStack.h"
#include "LeIpc7351/LandPattern.h"

#include "LeIpc7351/Arrangements/ArrayArrangement.h"
#include "LeIpc7351/Arrangements/CornerArrangement.h"
#include "LeIpc7351/Arrangements/DualArrangement.h"
#include "LeIpc7351/Arrangements/QuadInLineArrangement.h"

#include <QGridLayout>
#include <QSettings>

LandPatternWidget::LandPatternWidget(QWidget *parent)
    : EditorWidget(parent)
    , LDO::IDocumentObjectListener()
{
    setupScene();
    setupView();

    setLayout(new QGridLayout);
    layout()->addWidget(m_view);
    layout()->setMargin(0);
    layout()->setSpacing(0);
}

void LandPatternWidget::startTask(AbstractTask *task)
{
    //task->setView(m_view);
}

void LandPatternWidget::restoreGeometryAndState(QSettings &settings)
{
    settings.beginGroup(m_scene->objectName());
    m_scene->setSceneRect(settings.value("sceneRect").toRectF());
    settings.endGroup();

    settings.beginGroup(m_view->objectName());
    m_view->setVisibleSceneRect(settings.value("visibleSceneRect").toRectF());
    settings.endGroup();
}

void LandPatternWidget::saveGeometryAndState(QSettings &settings)
{
    settings.beginGroup(m_scene->objectName());
    settings.setValue("sceneRect", m_scene->sceneRect());
    settings.endGroup();

    settings.beginGroup(m_view->objectName());
    // sceneRect is the area of the scene visualized by this view
    // visibleSceneRect is the area of the scene currently displayed on the screen
    settings.setValue("visibleSceneRect", m_view->visibleSceneRect());
    settings.endGroup();
}

LeGraphicsScene *LandPatternWidget::scene() const
{
    return m_scene;
}

LeGraphicsView *LandPatternWidget::view() const
{
    return m_view;
}

void LandPatternWidget::setupScene()
{
    m_scene = new LeGraphicsScene(this);
    m_scene->setObjectName("scene");

    LeGraphicsPalette palette;
    palette.setBrush(LeGraphicsPalette::Background, Solarized::backgroundHighlight);
    palette.setBrush(LeGraphicsPalette::Grid, Solarized::secondaryContent);
    palette.setBrush(LeGraphicsPalette::Origin, Solarized::foreground);
    palette.setBrush(LeGraphicsPalette::Cursor, Solarized::foreground);
    palette.setBrush(LeGraphicsPalette::Selection, Solarized::foregroundHighlight);
    palette.setBrush(LeGraphicsPalette::Highlight, Solarized::foreground);
    palette.setBrush(LeGraphicsPalette::RubberBand, Solarized::foregroundHighlight);
    palette.setBrush(LeGraphicsPalette::BadMark, Solarized::red);
    palette.setBrush(LeGraphicsPalette::GoodMark, Solarized::green);
    //palette.setBrush(LeGraphicsPalette::Feature, Solarized::primaryContent);
    m_scene->setGraphicsPalette(palette);

    auto featureOption = LeGraphicsFeatureOption();
    featureOption.setAllFeatureVisible(true);
    featureOption.setAllFeatureBrush(QBrush(Solarized::foreground, Qt::SolidPattern));
    m_scene->foregroundLayer()->setFeatureOption(featureOption);
    m_scene->foregroundLayer()->setVisible(true);

    m_mcadLayer = new LeGraphicsItemLayer("mcad");
    featureOption = LeGraphicsFeatureOption();
    featureOption.setAllFeatureVisible(true);
    featureOption.setFeatureBrush(LeGraphicsFeature::GftNone, QBrush(Solarized::primaryContent, Qt::NoBrush));
    featureOption.setFeatureBrush(LeGraphicsFeature::GftPin, QBrush(Solarized::blue, Qt::SolidPattern));
    featureOption.setFeatureBrush(LeGraphicsFeature::GftPad, QBrush(Solarized::background, Qt::SolidPattern));
    featureOption.setFeatureBrush(LeGraphicsFeature::GftText, QBrush(Solarized::foregroundHighlight, Qt::SolidPattern));
    m_mcadLayer->setFeatureOption(featureOption);
    m_mcadLayer->setVisible(true);

    m_scene->setLayers(QList<LeGraphicsItemLayer*>() << m_mcadLayer);
}

void LandPatternWidget::setupView()
{
    m_view = new LeGraphicsView();
    m_view->setObjectName("view");
    m_view->setScene(m_scene);
    m_view->setInteractionMode(LeGraphicsView::MultipleSelectionMode);
    m_view->setOrientation(LeGraphicsView::XRightYUp);
}

void LandPatternWidget::addObject(LDO::IDocumentObject *object)
{
    Q_UNUSED(object)
}

void LandPatternWidget::removeObject(LDO::IDocumentObject *object)
{
    Q_UNUSED(object)
}

#include <QDebug>
#define DEBUG() qDebug() << __FUNCTION__

void LandPatternWidget::documentObjectAboutToBeInserted(LDO::IDocumentObject *parent, LDO::IDocumentObject *child, int index)
{
    Q_UNUSED(parent)
    Q_UNUSED(child)
    Q_UNUSED(index)
}

void LandPatternWidget::documentObjectInserted(LDO::IDocumentObject *parent,
                                               LDO::IDocumentObject *child,
                                               int index)
{
    Q_UNUSED(parent)
    Q_UNUSED(child)
    Q_UNUSED(index)
}

void LandPatternWidget::documentObjectAboutToBeRemoved(LDO::IDocumentObject *parent,
                                                       LDO::IDocumentObject *child,
                                                       int index)
{
    Q_UNUSED(parent)
    Q_UNUSED(child)
    Q_UNUSED(index)
}

void LandPatternWidget::documentObjectRemoved(LDO::IDocumentObject *parent,
                                              LDO::IDocumentObject *child,
                                              int index)
{
    Q_UNUSED(parent)
    Q_UNUSED(child)
    Q_UNUSED(index)
}

void LandPatternWidget::documentObjectPropertyChanged(const LDO::IDocumentObject *object,
                                                      const QString &name,
                                                      const QVariant &value)
{
    Q_UNUSED(object)
    Q_UNUSED(name)
    Q_UNUSED(value)
}


void LandPatternWidget::edit(MainWindow *gui, LDO::Document *document, LDO::IDocumentObject *object)
{
    m_gui = gui;
    m_document = document;
    beginListeningToDocumentObject(document);
    m_landPattern = qobject_cast<LandPattern*>(object);
}

LDO::IDocumentObject *LandPatternWidget::object() const
{
    return m_landPattern;
}

LDO::Document *LandPatternWidget::document() const
{
    return m_document;
}

QList<AbstractTask *> LandPatternWidget::tasks() const
{
    return QList<AbstractTask *>();
}

QString LandPatternWidget::title() const
{
    if (m_landPattern == nullptr)
        return QString();

    return m_landPattern->objectUserName();
}
